package info.batcloud.laxiaoke.open;

import com.alibaba.fastjson.JSON;
import info.batcloud.laxiaoke.open.annotation.Param;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DefaultLxkClient implements LxkClient {

    private Logger logger = LoggerFactory.getLogger(DefaultLxkClient.class);

    private String openId;

    private String serverUrl;

    public DefaultLxkClient(String serverUrl, String openId) {
        this.openId = openId;
        this.serverUrl = serverUrl;
    }

    @Override
    public <T extends LxkResponse> T execute(LxkRequest<T> request) {

        List<String> list = new ArrayList<>();
        Map<String, String> params = new HashMap<>();
        Class requestClazz = request.getClass();
        for (Field field : requestClazz.getDeclaredFields()) {
            field.setAccessible(true);
            try {
                Object val = field.get(request);
                if (val == null) {
                    continue;
                }
                if (field.isAnnotationPresent(Param.class)) {
                    Param param = field.getAnnotation(Param.class);
                    String strVal;
                    if (val instanceof List) {
                        strVal = JSON.toJSONString(val);
                    } else {
                        strVal = val.toString();
                    }
                    String key = (param.value() == null || param.value().trim().length() == 0) ? field.getName() : param.value();
                    params.put(key, strVal);
                } else {
                    params.put(field.getName(), val.toString());
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        params.put("openId", openId);
        params.forEach((k, v) -> {
            try {
                list.add(k + "=" + URLEncoder.encode(v, "utf8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        });
        String api = serverUrl + request.getUri() + "?" + String.join("&", list);
        logger.info("请求api：" + api);
        CloseableHttpClient client = HttpClientBuilder.create().build();
        try {
            HttpPost httpPost = new HttpPost(api);
            httpPost.setHeader("Content-Type", "application/json");
            HttpResponse res = client.execute(httpPost);
            String result = EntityUtils.toString(res.getEntity(), "utf8");
//            logger.info("api返回" + result);
            client.close();
            T response = JSON.parseObject(result, request.getResponseClass());
            return response;
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
